package org.yaac.client.ui;

import static com.google.common.base.Strings.isNullOrEmpty;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.yaac.client.i18n.ErrorMessages;
import org.yaac.client.util.AutoBeanUtil;
import org.yaac.client.widget.egql.EGQLErrorPanel;
import org.yaac.client.widget.egql.EGQLImmediatePanel;
import org.yaac.client.widget.egql.EGQLResultPanel;
import org.yaac.shared.egql.EGQLConstant;
import org.yaac.shared.egql.Result;


import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.TabLayoutPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

/**
 * @author Max Zhu (thebbsky@gmail.com)
 *
 */ 
public class EGQLViewImpl extends Composite implements EGQLView {

	private static QueryViewImplUiBinder uiBinder = GWT.create(QueryViewImplUiBinder.class);

	@UiTemplate("EGQLView.ui.xml")
	interface QueryViewImplUiBinder extends UiBinder<Widget, EGQLViewImpl> {
	}
	
	@UiField
	TextArea cmdTxt;
	
	@UiField
	Button goBtn;
	
	@UiField
	TextBox batchSizeTxt;
	
	@UiField
	TextBox maxResultTxt;
	
	@UiField
	TabLayoutPanel resultTabPanel;
	
	private Presenter listener;
	
	private Map<String, EGQLResultPanel> resultPanelMap;

	// i18n
	private final ErrorMessages errorMessages;
	
	/**
	 * 
	 */
	@Inject
	EGQLViewImpl(ErrorMessages errorMessages) {
		this.errorMessages = errorMessages;
		
		initWidget(uiBinder.createAndBindUi(this));
		
		resultTabPanel.setAnimationDuration(500);
		resultPanelMap = new HashMap<String, EGQLResultPanel>();
	}

	@Override
	public void setPresenter(Presenter listener) {
		this.listener = listener;
	}
	
	@UiHandler("goBtn")
	void onGoBtnClick(ClickEvent event) {
		if (isNullOrEmpty(batchSizeTxt.getText())) {
			batchSizeTxt.setText(String.valueOf(EGQLConstant.DEFAULT_BATCH_SIZE));
		}
		
		if (isNullOrEmpty(maxResultTxt.getText())) {
			maxResultTxt.setText(String.valueOf(EGQLConstant.DEFAULT_MAX_RESULT));
		}
		
		String batchSizeStr = batchSizeTxt.getText();
		String maxResultStr = maxResultTxt.getText();
		
		try {
			int batchSize = Integer.parseInt(batchSizeStr);
			int maxResult = Integer.parseInt(maxResultStr);
			
			String command = isNullOrEmpty(cmdTxt.getSelectedText()) ? 
					cmdTxt.getText() : cmdTxt.getSelectedText();
			this.listener.execute(command, batchSize, maxResult);
		} catch (NumberFormatException e) {
			Window.alert(e.getMessage());
		}
	}

	/* (non-Javadoc)
	 * @see org.yaac.client.ui.EGQLView#onMessage(java.lang.String)
	 */
	@Override
	public void onMessage(String msg) {		
		Result result = AutoBeanUtil.decode(Result.class, msg);

		EGQLResultPanel resultPanel = resultPanelMap.get(result.getStatementKey());
		
		if (resultPanel == null) {
			System.out.println("Ignored unexpected message from server side: ");
			System.out.println(msg);
			return;
		} 
		
		resultPanel.appendData(result.getResult());
		resultPanel.status(result.getStatus());
	}

	@Override
	public void onSyntaxError(String message) {
		newErrorMessage(message);
	}

	@Override
	public void onLogicalError(String errorCode) {
		newErrorMessage(errorMessages.getString(errorCode));
	}

	private void newErrorMessage(String msg) {
		EGQLErrorPanel errorPanel = new EGQLErrorPanel(msg);
		resultTabPanel.add(errorPanel);
		resultTabPanel.selectTab(errorPanel);
	}
	
	@Override
	public void prepareResultPanels(Map<String, String> stmtMap) {
		for (String id : stmtMap.keySet()) {
			if (!resultPanelMap.containsKey(id)) {
				EGQLResultPanel resultPanel = new EGQLResultPanel().withStatement(stmtMap.get(id));
				resultTabPanel.add(resultPanel);
				resultTabPanel.selectTab(resultPanel);	// switch to new tab
				resultPanelMap.put(id, resultPanel);
			}
		}
	}

	@Override
	public void generateImmediateResultPanel(List<String> immediateStmts) {
		if (!immediateStmts.isEmpty()) {
			StringBuilder sb = new StringBuilder();
			
			for (String stmt : immediateStmts) {
				sb.append("<div><b>");
				sb.append(stmt);
				sb.append("</b>");
				sb.append(" executed without any error");
				sb.append("</div>\n");
			}
			
			EGQLImmediatePanel panel = new EGQLImmediatePanel(sb.toString());
			resultTabPanel.add(panel);
			resultTabPanel.selectTab(panel);
		}
	}
}
